#ifndef EMAIL_H_INCLUDED
#define EMAIL_H_INCLUDED

#ifdef __cplusplus
extern "C"
{
#endif

#include "common.h"
#include "ini.h"

/* You need to set up a local server before defining USE_LOCAL_EMAIL_SERVER.
 * See http://code.google.com/p/cs1015project/wiki/SettingUphMailServer.
 */
//#define USE_LOCAL_EMAIL_SERVER

#define SMTPSERVER_GMAIL  "smtp.gmail.com"
#define SMTPPORT_GMAIL    587

#define SENDER_USERNAME_GMAIL		"cs1015project"
#define SENDER_ADDRESS_GMAIL		SENDER_USERNAME_GMAIL"@gmail.com"
#define SENDER_PASSWORD_GMAIL		"cs1015cs1015"

#define RECIPIENT_USERNAME_GMAIL    "vesteldemo"
#define RECIPIENT_ADDRESS_GMAIL	    RECIPIENT_USERNAME_GMAIL"@gmail.com"
#define RECIPIENT_PASSWORD_GMAIL	"vestelifa"

#define POP_MAILBOX_URL_GMAIL "pop3s://pop.gmail.com/1"

#ifdef USE_LOCAL_EMAIL_SERVER
    #define LOCAL_SERVER            "mail.local"
        
    #define SMTPSERVER_TEST         LOCAL_SERVER
    #define SMTPPORT_TEST           25

    #define SENDER_USERNAME_TEST	"test1"
    #define SENDER_ADDRESS_TEST	    SENDER_USERNAME_TEST"@"LOCAL_SERVER
    #define SENDER_PASSWORD_TEST	"test1"

    #define RECIPIENT_USERNAME_TEST	"test2"
    #define RECIPIENT_ADDRESS_TEST	RECIPIENT_USERNAME_TEST"@"LOCAL_SERVER
    #define RECIPIENT_PASSWORD_TEST	"test2"

    #define POP_MAILBOX_URL_TEST    "pop3://"LOCAL_SERVER"/"

    #define EMAIL_RECEPTION_MAX_CHECK_COUNT 100
#else
    #define SMTPSERVER_TEST	    SMTPSERVER_GMAIL
    #define SMTPPORT_TEST       SMTPPORT_GMAIL

    #define SENDER_USERNAME_TEST	SENDER_USERNAME_GMAIL
    #define SENDER_ADDRESS_TEST		SENDER_USERNAME_TEST"@gmail.com"
    #define SENDER_PASSWORD_TEST	SENDER_PASSWORD_GMAIL

    #define RECIPIENT_USERNAME_TEST RECIPIENT_USERNAME_GMAIL
    #define RECIPIENT_ADDRESS_TEST	RECIPIENT_USERNAME_TEST"@gmail.com"
    #define RECIPIENT_PASSWORD_TEST	RECIPIENT_PASSWORD_GMAIL

    #define POP_MAILBOX_URL_TEST    POP_MAILBOX_URL_GMAIL

    #define EMAIL_RECEPTION_MAX_CHECK_COUNT 10
#endif

#define HEADER_FIELD_BUFFER_LENGTH  1024
#define EMAIL_BUFFER_LENGTH         100000

#define EMAIL_HEADER_PREFIX_TO          "To: "
#define EMAIL_HEADER_PREFIX_FROM        "From: "
#define EMAIL_HEADER_PREFIX_SUBJECT     "Subject: "
#define EMAIL_HEADER_PREFIX_MESSAGE_ID  "Message-ID: "
#define MESSAGE_ID_SUFFIX               "@agilerss.org>"

#define DIGEST_EMAIL_SUBJECT_FORMAT     "agilerss digest (%s)" // insert date and time
#define STATISTICS_EMAIL_SUBJECT_FORMAT "agilerss statistics for %s" // insert month and year
#define STATISTICS_EMAIL_BODY           "Please see the attached file for this month's agilerss statistics."

enum
{
    EMAIL_RECEIVE_DATA_TIMEOUT_MS = 3000, // 2 seconds seem to be too low
    MAX_LENGTH_LAST_LINE_POP3_LIST = 20
};

/**
 * @param attachments NULL-terminated array of attachment file paths
 *
 * @return true if successful, false otherwise 
 */
//TODO: define a structure to keep all these parameters
bool EMAIL_Send(char * sender_address, char * recipient_address, char * subject,
    char * message_id, char * body, char ** attachments, format_opt_t format,
    char * smtp_server, int smtp_port, char * username, char * password);

/**
 * @return the return value will point to shared storage that will be changed 
 *         by subsequent calls to this function
 */
char * EMAIL_GenerateRandomMessageId();

/**
 * @return the return value will point to shared storage that will be changed 
 *         by subsequent calls to EMAIL_GenerateRandomMessageId()
 */
char * EMAIL_GetLastGeneratedMessageId();

size_t EMAIL_SaveAllReceivedDatatoMemory(void *contents, size_t size, size_t nmemb, void *userp);

/**
 * @param buffer    buffer which stores all data related received email.
 * @param field     command which tells what to do with the extracted data.
 *                  Current design supports AddFeed and AddCustomer commands.
 *
 * @brief Some mail protocols insert CRLN into subject string. This function deals with it
 *        to get the correct subject string.
 *        
 * @return string to add to ini file. 
 */

char * EMAIL_ExtractSubjectFromBuffer(char * buffer, char * field);

bool EMAIL_Receive(struct MemoryStruct *sample_chunk, const char * mailbox_url, 
    const char * username, char * password);

/**
 * @brief In order for this function to work properly, received email subject which includes commands
 *        should be like one of the following formats:
 *        ex1 : AddFeed http://www.cnnturk.com/servisler/rss/24/saglik.xml=
 *        ex2 : AddCustomer name, surname, abcdef@gmail.com, Digest:option, Format:option, timezone, keywords=
 */

void EMAIL_ExtractCommandData();

/**
 * @param customer_count    number of customers
 * @param customers         array of customer data
 *
 * @return true if successful, false otherwise 
 */
bool EMAIL_SendDigests(int customer_count, const customer_t * customers);

/**
 * @param customer_count    number of customers
 * @param customers         array of customer data
 *
 * @return true if successful, false otherwise 
 */
bool EMAIL_SendStatistics(int customer_count, const customer_t * customers);

/**
 * @param section_name    Section name in the ini file
 * @param command_data    Data to be written
 *
 * @return true if successful, false otherwise 
 */
bool EMAIL_WriteDataToINIFile(char* section_name, char* command_data);

#ifdef __cplusplus
}
#endif

#endif // EMAIL_H_INCLUDED
